import { useEffect, useRef } from "react";
import {
    ArcRotateCamera, Color4, Engine, HemisphericLight, Mesh, MeshBuilder, Plane, Scene,
    StandardMaterial, Vector3, Color3, DirectionalLight, Animation, CircleEase, EasingFunction,
} from '@babylonjs/core';


const canvas = document.createElement("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

const engine = new Engine(canvas, true);
const scene = new Scene(engine);


const camera = new ArcRotateCamera('Camera', Math.PI / 3, Math.PI / 3, 9, new Vector3(5, 5, 5), scene);
camera.attachControl(canvas, true);

const updateAction: ((time: number) => {})[] = [];

const light = new DirectionalLight('light02', new Vector3(-1, -1, 0), scene);
const ground = MeshBuilder.CreateGround('ground', { width: 10, height: 10, updatable: true }, scene);

const sphere = MeshBuilder.CreateSphere('sphere', { segments: 10, diameter: 3 }, scene);
sphere.position.set(0, 2, 0);

//参数2 : 类似于WPF中的动画属性
//参数3 : 每秒请求的帧数(每秒请求100帧表示一秒走100帧,即这个动画结束也是100帧,表示1秒内完成)
//参数4 : 动画的值的属性
//  注意:在矩阵模式下需要开启Animation.AllowMatricesInterpolation属性才可以进行插值计算, 否则会对矩阵的每一个值进行分别插值
//参数5 : 动画执行完后的行为模式
//  相对:Animation.ANIMATIONLOOPMODE_RELATIVE
//  循环:Animation.ANIMATIONLOOPMODE_CYCLE
//  停止:Animation.ANIMATIONLOOPMODE_CONSTANT
var animationBox = new Animation("myAnimation", "position.y", 100, Animation.ANIMATIONTYPE_FLOAT, Animation.ANIMATIONLOOPMODE_CONSTANT);
animationBox.setKeys([
    {
        frame: 0, value: 0,
        // outTangent: new Vector3(1, 0, 0)
    },
    {
        frame: 100, value: 2,
        // inTangent: new Vector3(-1, 0, 0),
    },
]);

var animationBox1 = new Animation("myAnimation1", "position.x", 100, Animation.ANIMATIONTYPE_FLOAT, Animation.ANIMATIONLOOPMODE_CONSTANT);
animationBox1.setKeys([
    {
        frame: 0, value: 0,
        // outTangent: new Vector3(1, 0, 0)
    },
    {
        frame: 100, value: 2,
        // inTangent: new Vector3(-1, 0, 0),
    },
]);

//动画混合模式(没搞懂)
// animationBox.enableBlending = true;//动画混合模式
// animationBox1.enableBlending = true;//动画混合模式

//缓动函数
var easingFunction = new CircleEase()
easingFunction.setEasingMode(EasingFunction.EASINGMODE_EASEINOUT);
animationBox.setEasingFunction(new CircleEase());


sphere.animations = [animationBox, animationBox1];
scene.beginAnimation(sphere, 0, 100, true);
// await scene.beginAnimation(sphere, 0, 100, true);//可以异步等待动画执行完毕
//权重执行(没搞懂)
// scene.beginWeightedAnimation(sphere, 0, 50, 1.0, true);
// scene.beginWeightedAnimation(sphere, 50, 100, 0.5, true);

//快速创建并执行(对于执行时长完全不明所以)
// Animation.CreateAndStartAnimation('animate01', sphere, 'position.y', 1, 2, 0, 1);


const RenderStructure = () => {
    const divRef = useRef<HTMLDivElement>(null);
    useEffect(() => {
        const { current } = divRef;
        if (current != null) {
            current.innerHTML = '';
            current.append(canvas);
            ani(0);
        }
    }, []);
    return (
        <div ref={divRef}></div>
    );
};

export default RenderStructure;

function ani(time: number) {
    updateAction.forEach((action) => {
        action(time);
    })
    scene.render();

    requestAnimationFrame(ani);
}